<?php

namespace App\Trip\Services\Train\Station;

use App\Facades\StationsGeoFacade;
use App\Models\Common\Area\Repositories\AreaRepository;
use App\Models\Common\Area\Repositories\Interfaces\AreaRepositoryInterface;
use App\Models\Train\Stations\Repositories\Interfaces\StationRepositoryInterface;
use App\Models\Train\Stations\Repositories\StationRepository;
use Illuminate\Support\Str;
use JetBrains\PhpStorm\ArrayShape;

class StationMap
{
    /**
     * @var StationRepository $stationRepo
     */
    private mixed $stationRepo;
    /**
     * @var AreaRepository $areaRepo
     */
    private mixed $areaRepo;

    public function __construct()
    {
        $this->stationRepo = app(StationRepositoryInterface::class);
        $this->areaRepo    = app(AreaRepositoryInterface::class);
    }

    public function write(): void
    {
        $maps        = $this->map();
        $js_map      = $maps['js_map'];
        $json_map    = $maps['json_map'];
        $json_map_zh = $maps['json_map_zh'];
        $json_map_xj = $maps['json_map_xj'];
        $s           = sprintf("var station_map ='%s'", $js_map);
        file_put_contents(public_path('Train/map_station.js'), $s);
        file_put_contents(public_path('Train/station.json'), $json_map);
        file_put_contents(public_path('Train/station_zh.json'), $json_map_zh);
        file_put_contents(public_path('Train/xj_station.json'), $json_map_xj);
    }

    #[ArrayShape([
        'js_map'      => "string",
        'json_map'    => "string",
        'json_map_zh' => "string",
        'json_map_xj' => "string",
    ])]
    public function map($keywords = ''): array
    {
        $stations    = $this->stationRepo->listStations();
        $js_map      = [];
        $json_map    = [];
        $json_map_zh = [];
        $json_map_xj = [];

        foreach ($stations as $key => $station) {
            $station->initial_uy = $station->initial_uy ?: '#';
            $city                = $this->areaRepo->findCityByCode($station->citycode);
            $ad                  = $this->areaRepo->findByCode($station->adcode);
            if ($ad && !$city) {
                $city = $this->areaRepo->findByCode($ad->getParentCode());
            }
            if (!$city || !$ad) {
                continue;
            }

            if (Str::contains($station->station_name, " ")) {
                continue;
            }

            if (!StationsGeoFacade::hasGeo($station->station_code)) {
                StationsGeoFacade::addGeoByStation($station);
            }

            $res      = [
                "@".$station->abbr,
                $station->initial_uy,
                $station->initial,
                $station->station_name,
                $station->station_name_uy,
                $station->station_code,
                $station->cityname,
                $city->getAreaNameUy(),
                $station->adname,
                $ad->getAreaNameUy(),
                $city->getAdCode(),
                $station->adcode,
                "#",
            ];
            $js_map[] = implode('|', $res);
            $iscity   = isUseCity($station->adname);
            $data     = [
                'initial_uy'      => $station->initial_uy,
                'initial'         => $station->initial,
                'station_name'    => $station->station_name,
                'station_name_uy' => $station->station_name_uy,
                'station_code'    => $station->station_code,
                'cityname'        => $station->cityname,
                'cityname_uy'     => $city->getAreaNameUy(),
                'adname'          => $station->adname,
                'adname_uy'       => $ad->getAreaNameUy(),
                'citycode'        => $city->getAdCode(),
                'adcode'          => $station->adcode,
                'iscity'          => $iscity,
            ];

            $json_map[$station->initial_uy][] = $data;
            $json_map_zh[]                    = collect($data)->except([
                'initial_uy',
                'station_name_uy',
                'cityname_uy',
                'adname_uy',
            ]);
            if ($station->pcode == 650000) {
                $json_map_xj[$station->initial_uy][] = $data;
            }
        }
        $json_map    = collect($json_map)->sortBy(fn($key, $v) => $v)->toJson(JSON_UNESCAPED_UNICODE);
        $json_map_zh = collect($json_map_zh)->sortBy(fn($key, $v) => $v)->toJson(JSON_UNESCAPED_UNICODE);
        $json_map_xj = collect($json_map_xj)->sortBy(fn($key, $v) => $v)->toJson(JSON_UNESCAPED_UNICODE);

        return [
            'js_map'      => implode('', $js_map),
            'json_map'    => $json_map,
            'json_map_zh' => $json_map_zh,
            'json_map_xj' => $json_map_xj,
        ];
//        $str = implode('', $maps);
//        $str = "@987|#@123|#"; // (@((?!#).)*?7.*?\|#)
//        $res = preg_match_all("/(@(?<station>((?!#).)*?{$keywords}.*?)\|#)/is", $str, $out);
//        dd($out['station'] ?? []);
//        return $str;
    }
}